package com.rh.zuul.filterpre;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import com.rh.entity.log.RenHaiLog;
import com.rh.entity.user.RenHaiUser;
import com.rh.zuul.filterorder.FilterOrder;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import renhai.util.ResponseContext;
import renhai.util.RestTemplateUtil;
import renhai.util.encrypt.AesEncryptUtil;
import renhai.util.log.LogUrl;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Date;

/**
 * @author 57556
 * 设置头部解决跨域问题
 */
@Component
public class HeaderFilter extends ZuulFilter {

    @Autowired
    private RestTemplateUtil restTemplateUtil;

    /**
     * 过滤器类型
     *
     * @return
     */
    @Override
    public String filterType() {//前置过滤器
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 顺序
     *
     * @return
     */
    @Override
    public int filterOrder() {//数值越小越早被执行
        return FilterOrder.FILTER_HEADER;
    }

    /**
     * 过滤器是否生效
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.sendZuulResponse();
    }

    /**
     * 业务逻辑
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        // 解决跨域问题
        HttpServletResponse response = ctx.getResponse();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        String url = request.getRequestURI();
        System.out.println("url:" + url);
        RenHaiLog renHaiLog = new RenHaiLog() {{
            setLogRequestUrl(url);
            setLogOperationTime(new Date());
            setLogRequestMethod("");
        }};
        if (FilterOrder.OVERLOOK_URL.get(url) == null) {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (!isMultipart) {
                try {
                    System.out.println(request.getParameterMap());
                    // 获取请求的输入流
                    InputStream in = request.getInputStream();
                    String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
                    // 如果body为空初始化为空json
                    if (StringUtils.isBlank(body)) {
                        body = "{}";
                    } else {
                        //参数解密
                        body = AesEncryptUtil.desEncrypt(body);
                        System.out.println(url+"         解密参数：" + body);
                    }
                    renHaiLog.setLogRequestData(body);
                    // 转化成json
                    JSONObject json = JSON.parseObject(body);
                    String newBody = json.toString();
                    final byte[] reqBodyBytes = newBody.getBytes();
                    // 重写上下文的HttpServletRequestWrapper
                    ctx.setRequest(new HttpServletRequestWrapper(request) {
                        @Override
                        public ServletInputStream getInputStream() throws IOException {
                            return new ServletInputStreamWrapper(reqBodyBytes);
                        }

                        @Override
                        public int getContentLength() {
                            return reqBodyBytes.length;
                        }

                        @Override
                        public long getContentLengthLong() {
                            return reqBodyBytes.length;
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else {
            renHaiLog.setLogRequestData("忽略地址，未加密数据");
        }
        RenHaiUser renHaiUser = restTemplateUtil.getUser(RenHaiUser.class);
        String ip = ctx.getZuulRequestHeaders().get("HTTP_X_FORWARDED_FOR");
        if (renHaiUser != null) {
            renHaiLog.setLogOperationUserId(renHaiUser.getUserId());
            renHaiLog.setLogOperationUserName(renHaiUser.getUserName());
            renHaiLog.setLogRequestIp(ip);
        }
        ResponseContext responseContext =  restTemplateUtil.postForObject2(LogUrl.SAVE_UPDATE, renHaiLog);
        if(responseContext!=null && responseContext.getEntity()!=null){
            ctx.getZuulRequestHeaders().put("log_id", responseContext.getEntity().toString());
            response.setHeader("log_id",responseContext.getEntity().toString());
        }
        return null;
    }
}
